#include <stdio.h>
#include <stdint.h>

union uint_float
{
	unsigned int i;
	float f;
};

float calculate_machine_epsilon(float start)
{
	union uint_float v;

	v.f = start;
	v.i++;

	return v.f - start;
}

int main()
{
	printf("%f\n", calculate_machine_epsilon(1.0));

	return 0;
}

#if 0
/*
 * intel
 */
0000000000001149 <calculate_machine_epsilon>:
    1149:	f3 0f 1e fa          	endbr64 
    114d:	55                   	push   %rbp
    114e:	48 89 e5             	mov    %rsp,%rbp
    1151:	f3 0f 11 45 ec       	movss  %xmm0,-0x14(%rbp)		// (rbp-0x14)=0x3f800000
    1156:	f3 0f 10 45 ec       	movss  -0x14(%rbp),%xmm0		// xmm0=0x3f800000
    115b:	f3 0f 11 45 fc       	movss  %xmm0,-0x4(%rbp)			// (rbp-0x4)=0x3f800000
    1160:	8b 45 fc             	mov    -0x4(%rbp),%eax			// eax=0x3f800000
    1163:	83 c0 01             	add    $0x1,%eax				// eax=0x3f800001
    1166:	89 45 fc             	mov    %eax,-0x4(%rbp)			// (rbp-0x4)=0x3f800001
    1169:	f3 0f 10 45 fc       	movss  -0x4(%rbp),%xmm0			// xmm0=0x3f800001
    116e:	f3 0f 5c 45 ec       	subss  -0x14(%rbp),%xmm0		// 0x3f800001-0x3f800000=0x34000000	--> 
																	// 1.0000001192092896 - 1.0 = 1.1920928955078125e-7
    1173:	5d                   	pop    %rbp
    1174:	c3                   	retq   

0000000000001175 <main>:
    1175:	f3 0f 1e fa          	endbr64 
    1179:	55                   	push   %rbp
    117a:	48 89 e5             	mov    %rsp,%rbp
    117d:	f3 0f 10 05 83 0e 00 	movss  0xe83(%rip),%xmm0        # 2008 <_IO_stdin_used+0x8>	// xmm0=0x3f800000=1.0
    1184:	00 
    1185:	e8 bf ff ff ff       	callq  1149 <calculate_machine_epsilon>
    118a:	f3 0f 5a c0          	cvtss2sd %xmm0,%xmm0			// xmm0=0x3e80000000000000
    118e:	48 8d 3d 6f 0e 00 00 	lea    0xe6f(%rip),%rdi        # 2004 <_IO_stdin_used+0x4>
    1195:	b8 01 00 00 00       	mov    $0x1,%eax
    119a:	e8 b1 fe ff ff       	callq  1050 <printf@plt>		// 0.000000
    119f:	b8 00 00 00 00       	mov    $0x0,%eax
    11a4:	5d                   	pop    %rbp
    11a5:	c3                   	retq   
    11a6:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)
    11ad:	00 00 00 

/*
 * arm
 */
000000000040055c <calculate_machine_epsilon>:
  40055c:	d10083ff 	sub	sp, sp, #0x20
  400560:	bd000fe0 	str	s0, [sp, #12]
  400564:	bd400fe0 	ldr	s0, [sp, #12]
  400568:	bd001be0 	str	s0, [sp, #24]
  40056c:	b9401be0 	ldr	w0, [sp, #24]
  400570:	11000400 	add	w0, w0, #0x1
  400574:	b9001be0 	str	w0, [sp, #24]
  400578:	bd401be1 	ldr	s1, [sp, #24]
  40057c:	bd400fe0 	ldr	s0, [sp, #12]
  400580:	1e203820 	fsub	s0, s1, s0
  400584:	910083ff 	add	sp, sp, #0x20
  400588:	d65f03c0 	ret

000000000040058c <main>:
  40058c:	a9bf7bfd 	stp	x29, x30, [sp, #-16]!
  400590:	910003fd 	mov	x29, sp
  400594:	1e2e1000 	fmov	s0, #1.000000000000000000e+00
  400598:	97fffff1 	bl	40055c <calculate_machine_epsilon>
  40059c:	1e22c000 	fcvt	d0, s0
  4005a0:	90000000 	adrp	x0, 400000 <_init-0x3e8>
  4005a4:	9119a000 	add	x0, x0, #0x668
  4005a8:	97ffffaa 	bl	400450 <printf@plt>
  4005ac:	52800000 	mov	w0, #0x0                   	// #0
  4005b0:	a8c17bfd 	ldp	x29, x30, [sp], #16
  4005b4:	d65f03c0 	ret


#endif

